/**
 * Utility stuff
 *
 * @author anders
 * @created 11.06.2011
 */

function log(content) {

//    var callzor = arguments.callee.caller;
    var prepender = log.timePrepender();

    $("#log").append("<div class=\"logentry\">" + prepender + "<span>" + content + "</span></div>");

    if (log.logentries >= 20) {
        $("#logentry" + (log.logentries - 20)).remove();
    }
}
log.noPrepender = function() {
    return "";
};
log.namePrepender = function(callzor) {
    var prepender;
    if (callzor.displayName) { // available in Joose classes
        prepender = "<b>" + callzor.displayName + "</b>";
    } else if (callzor.name) { // js function name (not available in IE apparently)
        prepender = "<b>" + callzor.name + "</b>";
    } else { // anonymous functions have no name
        prepender = "<b>unknown function</b>";
    }
    return pad(prepender, 50, "_");
};
log.timePrepender = function() {
    var oDate = new Date();
    var sTime = pad(oDate.getHours(), 2, "0", true) + ":" +
        pad(oDate.getMinutes(), 2, "0", true) + ":" +
        pad(oDate.getSeconds(), 2, "0", true) + ":" +
        pad(oDate.getMilliseconds(), 3, "0", true);
    return "<b>" + sTime + "</b> ";
};

function pad(text, len, ch, bPrepend) {
    text += ""; // cast
    if (text.length < len) {
        var diff = len - text.length;
        if (bPrepend) {
            var pad = "";
            for (var i = 0; i < diff; i++) pad += ch;
            text = pad + text;
        } else {
            for (var j = 0; j < diff; j++) text += ch;
        }
    }
    return text;
}

/**
 * Returns a random number between min and max
 * @param min
 * @param max
 * @returns {*}
 */
function rnd(min, max) {
    return min + Math.round(Math.random() * (max - min));
}

function rndElement(aElements) {
    return aElements[rnd(0, aElements.length-1)];
}

/**
 * Create a Namespace
 *
 * @param ns "com.example.application"
 * @param contents (object) is added to the leaf node (whatever is there already is preserved unless name conflicts)
 */
function namespace(ns, contents) {
    var aComponents = ns.split(".");
    var rootComponentName = aComponents[0];
    if (typeof window[rootComponentName] == "undefined") {
        window[rootComponentName] = {}; // insert global rdns root
    }
    // build namespace object hierarchy
    var componentName;
    var componentObj = window[rootComponentName];
    for (var i = 1; i < aComponents.length; i++) {
        componentName = aComponents[i];
        if (typeof componentObj[componentName] == "undefined") {
            componentObj[componentName] = {};
        }
        componentObj = componentObj[componentName];
    }
    $.extend(componentObj, contents); // add contents to the leaf node
}

/**
 * Create a daemon (function that is run repeatedly). Example usage:
 * <code>
 * daemon ( "Cache updater", 100, function updater() { ... });
 * </code>
 * Specifying a function name (eg. "updater") may be useful log info.
 *
 * @param name probably self explanatory
 * @param interval probably self explanatory
 * @param fn the function to be run repeatedly - should return true to continue, or false to stop the daemon.
 * @return void
 */
function daemon(name, interval, fn) {
    log("daemon started : " + name);

    function wrap() {
        var keepRunning = fn();
        if (keepRunning) {
            setTimeout(wrap, interval);
        }
    }
    wrap();
}

/**
 * Draw given a chance percent
 *
 * @param chance a decimal number between 0 and 1, eg 0.4 means 40% chance
 * @return boolean true if successfuly drew
 */
function draw(chance) {
    return rnd(0, 100) < chance * 100;
}

/**
 * Triggers a download (at least this works in chrome)
 */
function download(filename, text) {
    var dlAnchor = document.createElement('a');
    dlAnchor.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
    dlAnchor.setAttribute('download', filename);
    dlAnchor.click();
}